﻿#include "UdpClient.h"

extern QString currentStep;
extern QMap<int,QVariantMap> expLogInfo;
extern QMap<int,QVariantMap> expSendList;
extern int expStatus;//实验状态 0空闲 1实验中 2暂停
extern int expStep;
extern QString stepOperatingInfo;
UdpClient* UdpClient::Instance=0;
extern QVariantList logInfo;
extern QVector<double> cpsPartData;
extern QDateTime stepStartTime;
QStringList runningList;
extern bool haveConsumables;
extern bool heartMsg;

extern int  productSyringStep;//产物注射器步骤
extern bool isProductTesting;//产物检测
extern QDateTime productSyringStartTime;
extern bool firstConnect;

UdpClient* UdpClient::getInstance()
{
    if(Instance==0)
        Instance =new UdpClient();
    return Instance;
}

UdpClient::UdpClient(QObject *parent): QUdpSocket(parent)
{
    connect(this, &UdpClient::SignalConnectToHost, this, [&](const QString & address, quint16 port) {
        this->abort();
        this->bind(8080);
        this->connectToHost(QHostAddress(address), port, QIODevice::ReadWrite);
    }, Qt::AutoConnection);

    //收到了UDP服务的数据
    QObject::connect(this, &QIODevice::readyRead, this, [&]() {
        logClient = Loghelper::getInstance();

        QByteArray arr = this->readAll();
        QString str;
        for(int c :arr)
        {
            if(c>=0)
            {
                str += QString(" %1").arg(c, 2, 16, QChar('0')).toUpper();
            }
            else
            {
                str += QString(" %1").arg(c+256, 2, 16, QChar('0')).toUpper();
            }
        }
        str= str.simplified();

        if(str.length()>10)
        {
            QStringList list=str.split("62 00 ");
            for(int i=1;i<list.length();i++){
                QString info ="62 00 "+list[i];
                receiveDataProcessing(info.split(" "));
            }
            QMLSignal::I().emitRefCommunicationLog();
        }
    }, Qt::DirectConnection);

    //执行数据发送过程
    QObject::connect(this, &UdpClient::SignalSendingData, this, [&](const QByteArray c_btaData)
    {
        backSendData=c_btaData;
        this->write(c_btaData);

        QString str;
        for(int c :c_btaData)
        {
            if(c>=0)
            {
                str += QString(" %1").arg(c, 2, 16, QChar('0')).toUpper();
            }
            else
            {
                str += QString(" %1").arg(c+256, 2, 16, QChar('0')).toUpper();
            }
        }
        str= str.simplified();
        QStringList list=str.split(" ");
        saveLog("发送",list);

        QTimer::singleShot(4000, [this]() {
            if(!heartMsg)
                m_bOnLine=false;
        });
    }, Qt::AutoConnection);
}

//
UdpClient::~UdpClient()
{
}

//跨线程转换
void UdpClient::ClientConnectToHost(const QString & address, quint16 port)
{
    emit SignalConnectToHost(address, port);
}

//跨线程转换
void UdpClient::ClientSendingData(const QByteArray & c_btaData)
{
    emit SignalSendingData(c_btaData);
}

void UdpClient::receiveDataProcessing(QStringList list){
    if(list.length()>10)
    {
        saveLog("接收",list);
        if(list[0]=="62"&& list[1]=="00" && list[2]=="00" &&list[3]=="3A")
        {
            if(list[6]=="00" && list[7]=="02")//网络连接
            {
                heartMsg=true;
                m_bOnLine=true;
                QMLSignal::I().emitCommunicationStatus(0);     // 发信号通知前端
//                if(firstConnect){
//                    SignalSendingData(common->GetSendData(CommCommand::I().getMachineStatus()));
//                    firstConnect=false;
//                }
            }
            else if(list[6]=="01"&&list[7]=="02")//启动实验
            {
                AnimationManager::I().handleHEXInstrunction(list);

                currentStep="1";
                expStep=1;
                QMLSignal::I().experimentStatus("1",0);
                expStatus=1;
                ExperimentThread::I().run();
            }
            else if(list[6]=="02"&&list[7]=="02")//暂停
            {
                QMLSignal::I().experimentStatus("3",0);
            }
            else if(list[6]=="03"&&list[7]=="02")//继续
            {
                QMLSignal::I().experimentStatus("4",0);
            }
            else if(list[6]=="04"&&list[7]=="02")//停止
            {
                runningList.clear();
                QSqlDatabase db = dbHelper::openConnection();
                QSqlQuery query(db);
                QDateTime current=QDateTime::currentDateTime();
                QString dateStr=current.toString("yyyy-MM-dd");

                expStatus=0;
                currentStep="0";

                QString sql=QString("Update DataStatistics Set RubberPad=RubberPad+1 Where StaticDate='%1'").arg(dateStr);
                query.exec(sql);
                QMLSignal::I().experimentStatus("2",0);
            }
        }
        else if(list[0]=="62"&& list[1]=="00" && list[2]=="00" && list[3]=="3B")//实验指令
        {
            if(expStatus==1){
                if(list[7]=="02")//步骤完成
                {
                    if(productSyringStep==common->SixteenToTen(list[6]).toInt())
                    {
                        if(isProductTesting){
                            QString err = "1-1A 产物检测异常,未达到阈值 \n";
                            QMLSignal::I().emitSendErrorMsg(err,"否");
                        }
                        else{
                            qint64 msecs = QDateTime::currentDateTime().toMSecsSinceEpoch() - productSyringStartTime.toMSecsSinceEpoch();

                            expLogInfo[productSyringStep]["Status"]="完成";
                            expLogInfo[productSyringStep]["FinishTime"]= common->GetDateTimeStr();
                            expLogInfo[productSyringStep]["Time"]=QString::number(msecs);

                            QMLSignal::I().emitRefExperimentLog();
                        }
                    }
                    else {
                        expStep=common->SixteenToTen(list[6]).toInt()+1;
                        ExperimentThread::I().run();
                    }
                }
                else if(list[7]=="01")//确认收到信息(主要是为了发送给jnn操作前端动画)
                {
                    int nowStep=common->SixteenToTen(list[6]).toInt();
                    QVariantMap map= expSendList[nowStep];
                    AnimationManager::I().handleHEXInstrunction(map["Info"].toString().split(" "));
                }
                else //故障
                {
                    QString err;
                    QString method;
                    expStep=common->SixteenToTen(list[6]).toInt()+1;
                    for(int i=7;i<list.length()-4;i++)
                    {
                        QString gzdz = list[i];
                        QStringList gzdzv=common->getErrorInfo("2",gzdz);
                        if(gzdzv.length()>1)
                        {
                            if(!gzdzv[0].isNull()&&!gzdzv[0].isEmpty()){
                                err += QString::number(i-6)+"-"+gzdz+" "+gzdzv[0]+"\n";
                            }
                            if(!gzdzv[1].isNull()&&!gzdzv[1].isEmpty()){
                                method += gzdzv[1]+";";
                            }
                        }
                    }
                    if(err.length()>0){
                        if(method.contains("否")){
                            QMLSignal::I().emitSendErrorMsg(err,"否");
                        }else{
                            QMLSignal::I().emitSendErrorMsg(err,"是");
                        }
                    }
                    else
                    {
                        ExperimentThread::I().run();
                    }
                }
            }
            else
            {
                if(list[6]!="08" && list[7]=="02"){
                    QString pos= common->SixteenToTen(list[6]);
                    runningList.removeOne(pos);
                    QMLSignal::I().emitSendSyringRunMsg("0",pos);
                }
            }
        }
        else if(list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3C")//维护指令
        {
            if(list[6]=="02")//设置压力
            {
                if(list[7]=="00" && list[8]=="02"){

                    QString open=common->SixteenToTen(list[9]+" "+list[10]);
                    QString close=common->SixteenToTen(list[11]+" "+list[12]);

                    qDebug()<<open;
                    qDebug()<<close;
                    QMLSignal::I().emitSendAirPumpPressure(open,close);
                }
            }
            else if(list[6]=="04")//电机复位到实验位置
            {
                if(list[8]=="02")
                {
                    QString pos= common->SixteenToTen(list[7]);
                    if(pos=="0"){
                        runningList.clear();
                    }else{
                        runningList.removeOne(pos);
                    }
                    QMLSignal::I().emitSendResetMsg("0",pos);
                }
            }
            else if(list[6]=="05")//电机复位到光耦位置
            {
                if(list[8]=="02"){
                    QString pos= common->SixteenToTen(list[7]);
                    if(pos=="0"){
                        runningList.clear();
                    }else{
                        runningList.removeOne(pos);
                    }
                    QMLSignal::I().emitSendResetMsg("0",pos);
                }
            }
            else if(list[6]=="06")//注射器运动
            {
                if(list[8]=="02"){
                    QString pos= common->SixteenToTen(list[7]);
                    if(pos=="0"){
                        runningList.clear();
                    }else{
                        runningList.removeOne(pos);
                    }
                    QMLSignal::I().emitSendSyringRunMsg("0",pos);
                }
            }
            else if(list[6]=="08"){
                QString steps=common->SixteenToTen(list[7]+" "+list[8]+" "+list[9]+" "+list[10]);
                QMLSignal::I().emitSendTurnTablePos(steps);
            }
            else if(list[6]=="0C"){
                if(list[8]=="02"){
                    QString pos= common->SixteenToTen(list[7]);
                    runningList.removeOne(pos);
                }
            }
        }
        else if(list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3D")//接收上传数据
        {
            if(list[6]=="03")//速度数据
            {
                AnimationManager::I().handleHEXInstrunction(list);
            }
            else if(list[6]=="04"){
                if(list[7]=="00"&&list[8]=="00"){
                    QMLSignal::I().emitMaintenanceInfoChanged("压紧","是");
                }else{
                    QMLSignal::I().emitMaintenanceInfoChanged("压紧","否");
                }
            }
            else if(list[6]=="05"){
                if(list[7]=="00"){
                    haveConsumables=true;
                    QMLSignal::I().emitMaintenanceInfoChanged("芯片耗材","有");
                }else{
                    haveConsumables=false;
                    QMLSignal::I().emitMaintenanceInfoChanged("芯片耗材","无");
                }
            }
            else if(list[6]=="06"){
                if(list[7]=="00"){
                    QMLSignal::I().emitMaintenanceInfoChanged("废液瓶","有");
                }else{
                    QMLSignal::I().emitMaintenanceInfoChanged("废液瓶","无");
                }
            }
            else if(list[6]=="07"){
                if(list[7]=="00"){
                    QMLSignal::I().emitMaintenanceInfoChanged("产物瓶","有");
                }else{
                    QMLSignal::I().emitMaintenanceInfoChanged("产物瓶","无");
                }
            }
        }
    }
}

void UdpClient::saveLog(QString type,QStringList list)
{
    QString str=list.join(" ");

    //接收日志处理
    if(list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3D")//下位机上传数据
    {
        logClient->WriteLog("LcUploadInfoLog",QString("%1:\n"+str).arg(type));
    }
    else if(list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3A" && list[6]=="00")
    {
        logClient->WriteLog("HeartLog",QString("%1:\n"+str).arg(type));
    }
    else
    {
        logClient->WriteLog("CommLog",QString("%1:\n"+str).arg(type));

        QStringList logList;
        logList.append(common->GetDateTimeStr());
        logList.append(type);
        logList.append(str);
        logInfo.append(logList);
        QMLSignal::I().emitRefCommunicationLog();
    }

}

//是否在线
bool UdpClient::IsOnline()
{
    return m_bOnLine;
}
